﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Logging.Console;
using System;
using System.Collections.Generic;
using System.Text;

namespace DotNetExtensions.Core.Logging
{
    public class LoggerManager : Singleton<LoggerManager>
    {
        private ILoggerFactory loggerFactory;
        public ILoggerFactory Factory => loggerFactory;
        private LoggerManager()
        {
            loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Debug);
                builder.AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter<ConsoleLoggerProvider>("DotNetExtensions.Core", LogLevel.Debug)
                .AddConsole();
            });
        }
        public ILoggerFactory AddProvider<T, O>() where T : class, ILoggerProvider where O : class
        {
           
            loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.SetMinimumLevel(LogLevel.Debug);
                builder.AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter<ConsoleLoggerProvider>("DotNetExtensions.Core.Logging", LogLevel.Debug)
                .AddFilter<T>("DotNetExtensions.Core.Logging", LogLevel.Debug)
                .AddConsole();

                builder.AddConfiguration();
                builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, T>());
                LoggerProviderOptions.RegisterProviderOptions<O, T>(builder.Services);

                builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, ConsoleLoggerProvider>());
                LoggerProviderOptions.RegisterProviderOptions<ConsoleLoggerOptions, ConsoleLoggerProvider>(builder.Services);
            });
            return loggerFactory;
        }
        public ILogger Create()
        {
            return loggerFactory.CreateLogger("DotNetExtensions.Core.Logging");
        }
        public ILogger Create(string category)
        {
            return loggerFactory.CreateLogger(category);
        }
        public ILogger<T> Create<T>()
        {
            return loggerFactory.CreateLogger<T>();
        }

        public static ILogger GetLogger()
        {
            return Default.Create();
        }

        public static ILogger GetLogger(string category)
        {
            return Default.Create(category);
        }
        public static ILogger<T> GetLogger<T>()
        {
            return Default.Create<T>();
        }

        public static ILoggerFactory Add<TProvider,TOption>() where TProvider : class, ILoggerProvider where TOption : class
        {
            return Default.AddProvider<TProvider,TOption>();
        }
    }
}
